package com.atguigu.web;

import com.atguigu.utils.WebUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//写这个接口,是为了让其他跟user相似的业务也可以通过反射的原理,执行指定action的方法
//在接口中写死,按action,反射执行类对象的action同名方法
//在相似业务类上实现这个接口,顺理成章的具有了上一行的方法:doPost().
//业务进入到实现类,自动执行doPost(),自动获取action,自动反射执行action方法
public abstract class BaseServlet extends HttpServlet {//抽象类要用abstact修饰,抽象类和接口的差别是"类只能单一继承抽象类,类可以实现多个接口"
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        String action= request.getParameter("action");
        System.out.println(Thread.currentThread().getStackTrace()[1].getFileName()+":"
                +Thread.currentThread().getStackTrace()[1].getLineNumber()+":"
                +"已经进入dopost方法,执行名为"+action+"的方法");
//        if (action.equalsIgnoreCase("login")){
//            System.out.println("登录操作");
//            login(request,response);//这里把代码提到上面去,1,是为了使代码够清晰,2,是为了营造一个action是什么就执行什么方法的环境,为发射的运用做好准备
//            //反射,就是,用类的类对象,获取公布的方法中的某一个方法
//            //反射,还是,用类的类对象,获取公布的属性中的某个一个属性
//            //反射,还是,用类的类对象,获取公布的父类的父类数组成员们 (接口同理)
//            //反射,还是,用类的类对象,创造一个实例对象,并获取类对象的一个属性,属性set值进入实例对象,从而实例对象可以get到这个值的变化.
//                //这种操作,没有使用实例对象的set属性方法,而是用到了类对象的set属性方法,并指明了把这个属性给哪个实例对象.
//        }else{
//            System.out.println("注册操作");
//            regist(request,response);
//        }
// 注释了用反射的方法
        try {
            Method method=this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this,request,response);//this表示当前的实例对象
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            throw new RuntimeException(e);//遇到异常,要往上层抛,才行,不能自己知道,自己捂起来
            //往上抛之后,知道上层某一层输出,且不往上层继续抛,方才停止
        }
    }
}
